from typing import Dict, Any

from fastapi import APIRouter, Depends, Body

from common.pkg.fastapi_util import cbv
from common.route.mall_route import MallMatchAPIRoute
from common.route.route import ZipCustomerRoute
from common.route.tenant_route import TenantBaseAPIRoute
from common.utils.depends.common import get_current_tenant, Page, get_page_info
from common.utils.depends.tips_depends import get_auth_code, get_login_tenant
from common.utils.resp import JsonResponse, RC
from core.view import TenantBaseView
from schema.req_schema.spu_req_schema import AddNewSPUModel, BulkSPUModel, UpdateSPUReqModel
from service.spu_service import SPUService
from service.tenant_service import TenantCurrencyService

router = APIRouter(prefix="/spu", tags=["spu"], route_class=ZipCustomerRoute(TenantBaseAPIRoute, MallMatchAPIRoute),
                   dependencies=[Depends(get_auth_code), Depends(get_login_tenant)])


@cbv(router)
class SPUView(TenantBaseView):

    @router.post("/", description="新增商品")
    async def new_spu(self,
                      spu: AddNewSPUModel = Body(...),
                      tenant_info: Dict[str, Any] = Depends(get_current_tenant)):
        tcs = TenantCurrencyService(self.mgw, self.redis)
        default_currency = await tcs.get_default_currency(tenant_info.get("tenant_id"))
        if not default_currency:
            return JsonResponse.inner_error(exception_track=f"缺失默认币种信息", msg="缺失信息,请联系管理员!")
        spu.currency = default_currency
        spu_s = SPUService(self.mgw, self.redis)
        ok, data_or_code = await spu_s.create_new_spu(self.mall_id, spu)
        return self.unpack_response(ok, data_or_code)

    @router.get("/", description="获取商品列表")
    async def spu_list(self,
                       page_info: Page = Depends(get_page_info),
                       # query_model: SearchSPUListModel = Query(None, description="商品搜索条件")
                       ):
        spu_s = SPUService(self.mgw, self.redis)
        ok, data_or_code = await spu_s.get_spu_list(self.mall_id, page_info)
        return self.unpack_response(ok, data_or_code)

    @router.get("/{spu_id:int}", description="获取商品详情")
    async def spu_detail(self, spu_id: int):
        spu_s = SPUService(self.mgw, self.redis)
        ok, data_or_code = await spu_s.get_spu_detail_with_sku(self.mall_id, spu_id)
        return self.unpack_response(ok, data_or_code)

    @router.put("/{spu_id:int}", description="更新商品基本信息")
    async def modify_spu_info(self,
                              spu_id: int,
                              req_model: UpdateSPUReqModel = Body(...),
                              ):
        ss = SPUService(self.mgw, self.redis)
        ok, data_or_code = await ss.update_spu_info(self.mall_id, spu_id, req_model)
        return self.unpack_response(ok, data_or_code)

    @router.delete("/{spu_id:int}", description="删除商品")
    async def delete_spu(self, spu_id: int):
        spu_s = SPUService(self.mgw, self.redis)
        spu_info = await spu_s.get_spu_detail(self.mall_id, spu_id, ["version"])
        if not spu_info:
            return JsonResponse(code=RC.NOT_EXIST, msg="商品不存在").to_response()
        ok, data_or_code = await spu_s.delete_spu(self.mall_id, spu_id, spu_info.get("version"))
        return self.unpack_response(ok, data_or_code)

    @router.put("/status/bulk", description="批量设置spu的上下架状态")
    async def bulk_set_spu_onsale_status(self,
                                         req_model: BulkSPUModel = Body(...)):
        spu_s = SPUService(self.mgw, self.redis)
        ok, data_or_none = await spu_s.bulk_set_spu_status(self.mall_id, req_model)
        return self.unpack_response(ok, data_or_none)

    @router.put("/{spu_id:int}/sku/{sku_id:int}", description="设置某个商品的的某个sku的上下架状态")
    async def set_onsale_status_on_sku(self,
                                       spu_id: int,
                                       sku_id: int,
                                       onsale: bool = Body(..., embed=True)
                                       ):
        ss = SPUService(self.mgw, self.redis)
        ok, data_or_code = await ss.update_sku_onsale_status(self.mall_id, spu_id, sku_id, onsale)
        return self.unpack_response(ok, data_or_code)


